#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sqlite3.h>

#define BACKLOG 10
#define MSG_STR "Hello, you have connected to the server successfully!\n\n"

int g_stop = 0;

void sig_stop(int signum)
{
    	if (SIGINT == signum)		
    	{
    		printf("SIGINT signal detected\n");
        	g_stop = 1;
	}
}

int database_insert(sqlite3 *db, char *buf)
{
	char sql[128] = {};
	char *errmsg;

	sprintf(sql,"insert into temperature values(%s)", buf);

	if((sqlite3_exec(db, sql, NULL, NULL, &errmsg)) != SQLITE_OK)
	{
		printf("Insert data into table unsuccessfully : %s\n", errmsg);
	}
	else
	{
		printf("Insert data into table successfully!\n");
	}

	return 0;
}

int main(int argc, char *argv[])
{
    	int 				rv;
    	int                     	port = 8889;
    	int                     	on = 1;
    	int                     	server_fd = -1;
    	int                     	client_fd = -1;
    	pid_t                   	pid = -1;
    	struct sockaddr_in      	server_addr;
    	struct sockaddr_in      	client_addr;
    	socklen_t               	clientaddr_len = 20;
	int				daemon_start = 1;
	int				log_fd;
	char				sql[128];
	char 				*errmsg;
	sqlite3 			*db;

	if((sqlite3_open("temperature.db", &db)) != SQLITE_OK)
	{
		printf("Open database unsuccessfully : %s\n", sqlite3_errmsg(db));
		exit(1);
	}
	else
	{	
		printf("Open database successfully!\n");
	}

	if((sqlite3_exec(db, "create table if not exists temperature(infor varchar(100));", NULL, NULL, &errmsg)) != SQLITE_OK)
	{
		printf("Create table unsuccessfully : %s\n", errmsg);
		exit(1);
	}
	else
	{
		printf("Create table successfully!\n");
  	}
    	signal(SIGINT, sig_stop);

    	server_fd = socket(AF_INET, SOCK_STREAM, 0);
    	if (server_fd < 0)
    	{
        	printf("Creat socket unsuccessfully : %s\n", strerror(errno));
        	return 0;
    	}
    	printf("Creat the server[%d] successfully!\n",server_fd);

    	memset(&server_addr, 0, sizeof(server_addr));
    	server_addr.sin_family = AF_INET;		
    	server_addr.sin_port = htons(port);	
    	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    	setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); 

    	rv = bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    	if (rv < 0)
    	{
        	printf("Bind server's port unsuccessfully:%s\n", strerror(errno));
        	return 0;
    	}
    	printf("The port[%d] has been binded by this server!\n", port);

    	listen(server_fd, BACKLOG);

	if ( !daemon_start )
	{
		printf("Program is running in the background!\n");

		log_fd = open("temperature.log", O_CREAT|O_RDWR, 777);
		if (log_fd < 0)
		{
			printf("Open temperature.log unsuccessfully : %s", strerror(errno));
			return 0;
		}

		dup2(log_fd, STDOUT_FILENO);
		dup2(log_fd, STDERR_FILENO);

		if((daemon(1,1)) < 0)
		{
			printf("Create daemon unsuccessfully : %s", strerror(errno));
			return 0;
		}

	}



    	while (!g_stop)
    	{	
        	client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &clientaddr_len);
        	if (client_fd < 0)
        	{
            		printf("Accept request from client unsuccessfully : %s\n", strerror(errno));
            		continue;
        	}
        	printf("Accept request from client[%s:%d] successfully!\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
		
        	pid = fork();		
        	if (pid < 0)
        	{
            		printf("Create child process unsuccessfully : %s.\n", strerror(errno));
			close(client_fd);
            		continue;
        	}
        	else if (pid > 0)
        	{
            		close(client_fd);	
            		continue;
        	}
        	else if (pid == 0)
        	{
			char			buf[1024];

            		close(server_fd);	

			while(1)
            		{
                		memset(buf, 0, sizeof(buf));               
                		rv = read(client_fd, buf, sizeof(buf));	
                		if (rv < 0)		
                		{
                    			printf("Read information from client unsuccessfully : %s\n", strerror(errno));
                    			close(client_fd);
					exit(0);
                		}
                		else if (rv == 0)		
                		{
                    			printf("The client[%d] get disconnected!\n", client_fd);
                    			close(client_fd);
					exit(0);
                		}
                		else		
                		{
                    			printf("The message recived from client[%s,%d] : \n%s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);

					sprintf(sql,"insert into temperature values('%s');", buf);

					if((sqlite3_exec(db, sql, NULL, NULL, &errmsg)) != SQLITE_OK)
					{
						printf("Insert data into table unsuccessfully : %s\n", errmsg);
					}
					else
					{
						printf("Insert data into table successfully!\n\n");
					}
                		}
				
				rv = write(client_fd, MSG_STR, strlen(MSG_STR));
				if (rv < 0)
				{
					printf("Write to client unsuccessfully : %s\n", strerror(errno));
					close(client_fd);
				}

            		}
   		}
    	}
	close(server_fd);
	
    	return 0;
}

